/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.muni.fi.pa165.soccergamesarchive.businesslayer.services;

import cz.muni.fi.pa165.soccergamesarchive.businesslayer.dtos.TeamDTO;
import cz.muni.fi.pa165.soccergamesarchive.businesslayer.dtos.TeamDetailDTO;
import cz.muni.fi.pa165.soccergamesarchive.errorhandling.ErrorHandler;
import cz.muni.fi.pa165.soccergamesarchive.persistencelayer.daos.TeamDAO;
import cz.muni.fi.pa165.soccergamesarchive.persistencelayer.entities.Team;
import cz.muni.fi.pa165.soccergamesarchive.validators.ValidatorTest;
import java.util.List;
import java.util.Map;
import javax.annotation.security.DeclareRoles;
import javax.annotation.security.RolesAllowed;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;

import static cz.muni.fi.pa165.soccergamesarchive.errorhandling.ErrorHandler.createErrorMessage;
import static cz.muni.fi.pa165.soccergamesarchive.utils.EntityDTOTransformer.transform;
import static cz.muni.fi.pa165.soccergamesarchive.utils.EntityDTOTransformer.transformList;
import static cz.muni.fi.pa165.soccergamesarchive.validators.TeamValidator.validateTeam;

/**
 *
 * @author Martin
 *
 * <strong>EDITED BY: Michal Ďuriš</strong>
 */
@DeclareRoles("Archiver")
@Stateless(name = "TeamService")
public class TeamServiceBean implements TeamServiceBeanLocal {

    @EJB
    private TeamDAO teamEntityManager;

    public TeamServiceBean() {
    }

    public TeamDAO getTeamEntityManager() {
        return teamEntityManager;
    }

    public void setTeamEntityManager(TeamDAO teamEntityManager) {
        this.teamEntityManager = teamEntityManager;
    }

    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    @RolesAllowed("Archiver")
    @Override
    public TeamDTO addTeam(TeamDTO team) throws RuntimeException {

        Team teamEntity = transform(team, Team.class);

        int error = validateTeam(teamEntity,
                ValidatorTest.NULL_TEST);

        if (error != ErrorHandler.NO_ERROR) {
            throw new IllegalArgumentException(createErrorMessage(
                    this.getClass().getName(), error));
        }

        teamEntityManager.addTeam(teamEntity);

        return transform(teamEntity, TeamDTO.class);
    }

    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    @RolesAllowed("Archiver")
    @Override
    public TeamDTO changeTeam(TeamDTO team) throws RuntimeException {

        Team teamEntity = transform(team, Team.class);

        int error = validateTeam(teamEntity,
                ValidatorTest.NULL_TEST, ValidatorTest.ID_TEST);

        if (error != ErrorHandler.NO_ERROR) {
            throw new IllegalArgumentException(createErrorMessage(
                    this.getClass().getName(), error));
        }

        teamEntity = teamEntityManager.changeTeam(teamEntity);

        return transform(teamEntity, TeamDTO.class);
    }

    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    @RolesAllowed("Archiver")
    @Override
    public void removeTeam(TeamDTO team) throws RuntimeException {

        Team teamEntity = transform(team, Team.class);

        int error = validateTeam(teamEntity,
                ValidatorTest.NULL_TEST, ValidatorTest.ID_TEST);

        if (error != ErrorHandler.NO_ERROR) {
            throw new IllegalArgumentException(createErrorMessage(
                    this.getClass().getName(), error));
        }

        teamEntityManager.removeTeam(teamEntity);
    }

    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    @Override
    public List<TeamDTO> getAllTeams() {

        return transformList(teamEntityManager
                .getAllTeams(), TeamDTO.class);
    }

    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    @Override
    public List<TeamDTO> getLimitedNumberOfTeams(int offset, int limit,
                                                 Map<String, Object> filterMap,
                                                 Map<String, Boolean> orderMap)
            throws RuntimeException {

        if (offset < 0 || limit <= 0) {
            throw new IllegalArgumentException(createErrorMessage(
                    this.getClass().getName(), ErrorHandler.ILLEGAL_VALUE_ERROR));
        }

        List<Team> teams = teamEntityManager.getLimitedNumberOfTeams(offset,
                limit, filterMap,
                orderMap);

        return transformList(teams, TeamDTO.class);
    }

    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    @Override
    public TeamDTO getTeamById(Long teamId) throws RuntimeException {

        if (teamId == null || teamId.intValue() < 1) {
            throw new IllegalArgumentException(createErrorMessage(
                    this.getClass().getName(), ErrorHandler.ILLEGAL_VALUE_ERROR));
        }

        Team teamEntity = teamEntityManager.getTeamById(teamId);

        return transform(teamEntity, TeamDTO.class);
    }

    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    @Override
    public TeamDetailDTO getTeamDetail(Long id) throws RuntimeException {

        if (id == null || id < 1) {
            throw new IllegalArgumentException(createErrorMessage(
                    this.getClass().getName(), ErrorHandler.ILLEGAL_VALUE_ERROR));
        }

        TeamDetailDTO teamDetail = null;

        Team team = teamEntityManager.getTeamById(id);

        if (team != null) {

            teamDetail = new TeamDetailDTO();

            teamDetail.setTeam(transform(team,
                    TeamDTO.class));

            teamDetail.setStatistics(teamEntityManager.getTeamStatistics(team));
        }

        return teamDetail;
    }

    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    @Override
    public List<TeamDTO> findTeam(String searchString) throws RuntimeException {

        if (searchString == null || searchString.equals("")) {
            throw new IllegalArgumentException(createErrorMessage(
                    this.getClass().getName(), ErrorHandler.ILLEGAL_VALUE_ERROR));
        }

        return transformList(teamEntityManager.findTeam(
                searchString),
                TeamDTO.class);
    }

    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    @Override
    public List<Integer> getAvaliableShirtNumbers(TeamDTO team) throws
            RuntimeException {

        Team teamEntity = transform(team, Team.class);

        int error = validateTeam(teamEntity,
                ValidatorTest.NULL_TEST, ValidatorTest.ID_TEST);

        if (error != ErrorHandler.NO_ERROR) {
            throw new IllegalArgumentException(createErrorMessage(
                    this.getClass().getName(), error));
        }

        return teamEntityManager.getAvaliableShirtNumbers(teamEntity);
    }

    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    @Override
    public int getFilteredTeamsCount(Map<String, Object> filterMap) throws
            RuntimeException {

        return teamEntityManager.getFilteredTeamsCount(filterMap);
    }

}
